package com.liao.rent.filter;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.liao.rent.entity.SysUserDetails;
import com.liao.rent.service.RedisService;
import com.liao.rent.utils.JwtUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: ljt
 * @Description: JWT校验过滤器
 * @DateTime: 2024/11/26 下午1:56
 **/

@Component
public class JWTAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    RedisService redisService;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {




//        添加放行白名单
        List<String> whiltList = new ArrayList<>();
        whiltList.add("/sysUser/login");
        whiltList.add("/doc.html");
        whiltList.add("/swagger-ui/index.html");
        whiltList.add("/swagger-ui");
        whiltList.add("/webjars/");
        whiltList.add("/sysUser/regist");
        whiltList.add("/v3/api-docs/swagger-config");
        whiltList.add("/hybridaction/zybTrackerStatisticsAction");
//        放行系统注册请求
        whiltList.add("/sysUser/regist");

        for (String url:whiltList){
            if (request.getRequestURI().startsWith(url)){
                filterChain.doFilter(request,response);
                return;
            }
        }

//        logger.info(request.getRequestURI());

        for (String url:whiltList){
            if (url.startsWith(request.getRequestURI())){
                filterChain.doFilter(request,response);
                return;
            }
        }
//获取请求头中的token
        String token = request.getHeader("token");
//判断是否为空
        if (token == null || token.isEmpty()) {
//            请求携带异常信息，方便后续返回
            request.setAttribute("errMsg", "token缺失");
            throw new BadCredentialsException("token缺失");
        }

        String subject = "";

//获取token中的用户标识
        try {
            DecodedJWT decodedJWT = jwtUtil.VerifyToken(token);
             subject = decodedJWT.getSubject();
        }catch (Exception e){
//            请求携带异常信息，方便后续返回
            request.setAttribute("errMsg", "token无效");
            throw new BadCredentialsException("token无效");
        }
//获取redis中的用户信息
        SysUserDetails userDetails = (SysUserDetails) redisService.get(subject);

        if (userDetails == null) {
            //            请求携带异常信息，方便后续返回
            request.setAttribute("errMsg", "token过期");
            throw new BadCredentialsException("token过期");
        }

//        将用户信息存入SecurityContextHolder
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

    filterChain.doFilter(request,response);
    }
}
